/**
 * Copyright (c) 2016-2020 https://github.com/zhaohuatai
 *
 * contact 824069438@qq.com
 *  
 */
package org.zfes.snowy.auth.biz.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zfes.snowy.auth.biz.dao.AuthMenuMapper;
import org.zfes.snowy.auth.biz.model.AuthMenu;
import org.zfes.snowy.auth.biz.model.AuthPermission;
import org.zfes.snowy.auth.biz.service.IAuthAppService;
import org.zfes.snowy.auth.biz.service.IAuthMenuService;
import org.zfes.snowy.auth.biz.service.IAuthPermissionService;
import org.zfes.snowy.auth.biz.util.MenuUtil;
import org.zfes.snowy.auth.biz.view.MenuView;
import org.zfes.snowy.auth.manager.IAuthManager;
import org.zfes.snowy.core.idcenter.IDGenerator;
import org.zfes.snowy.core.data.DataSet;
import org.zfes.snowy.base.dao.enums.QueryType;
import org.zfes.snowy.base.dao.params.ParamMap;
import org.zfes.snowy.core.util.ZAlert;
import org.zfes.snowy.core.util.ZAssert;
import org.zfes.snowy.core.util.ZBeanUtil;
import org.zfes.snowy.core.util.ZObjectUtil;
import org.zfes.snowy.core.util.ZStrUtil;

import com.google.common.collect.Lists;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@Service
@Lazy(true)
public class AuthMenuServiceImpl implements IAuthMenuService{
 	@Autowired
	private AuthMenuMapper authMenuMapper;
 	@Autowired
	private IAuthPermissionService authPermissionService;
	
	@Autowired
	private IAuthAppService authAppService;
	@Autowired
	private IAuthManager  authManager;
	private Optional<Long> getAppId(String appKey){
		Optional<Long> appId=authAppService.loadIdByAppkey(appKey, true);
		return appId;
	}
 	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<MenuView> loadUserMenus(Long userId,String appkey,Boolean isLoadFromAllRole) {
		List<Long> permsIdList=Lists.newArrayList();
		
		Optional<Long> appId= getAppId(appkey);
		if(!appId.isPresent()){
			return Optional.empty();
		}
		if(isLoadFromAllRole){
			permsIdList=authManager.loadPermIdsInUserAllRoles(userId, appkey, true);
		}else{
			permsIdList=authManager.loadPermIdsInUserDefaultRole(userId, appkey, true);
		}
		
 		if(ZObjectUtil.isEmpty(permsIdList)){
			return Optional.empty();
		}
 		List<AuthPermission> per=authPermissionService.loadPermListByIds(permsIdList);
		if(ZObjectUtil.isEmpty(per)){
			return Optional.empty();
		}
	
		List<AuthMenu> authMenus=authMenuMapper.selectByAppKey(appkey);
		if(ZObjectUtil.isEmpty(authMenus)){
			return Optional.empty();
		}
		
		AuthMenu rootMenu=authMenuMapper.selectRootMenu();
		if(rootMenu==null){
			return Optional.empty();
		}
		MenuView rootMenuNode=new MenuView();
		MenuUtil.traverseMenuTree(rootMenu, rootMenuNode, per, authMenus);
		return Optional.ofNullable(rootMenuNode);
	}
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public DataSet loadAuthMenuTreeGrid(String appKey,Map<String,Object> params) {
		ParamMap pm=ParamMap.filterParam(params);
		pm.getStr("name").ifPresent(v -> pm.updateParam( "name", "%"+v+"%"));
		getAppId( appKey).ifPresent(val->pm.updateParam("appId", val));
		DataSet ds=DataSet.newDS(authMenuMapper.selectAuthMenuListCount(pm), authMenuMapper.selectAuthMenuList(pm));
		return ds;
	
	}
	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void createAuthMenu(AuthMenu authMenu) {
		ZBeanUtil.validateBean(authMenu);
		authMenu.setId(IDGenerator.genLongId());
		authMenuMapper.insertSelective(authMenu);
	}
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<AuthMenu> loadAuthMenuById(Long id) {

		if(id!=null){
			return Optional.ofNullable(authMenuMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();
	}
	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void updateAuthMenu(AuthMenu authMenu) {
		ZBeanUtil.validateBean(authMenu);
		authMenuMapper.updateByPrimaryKeySelective(authMenu);
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void setAuthMenuEnabled(List<Long> ids, Boolean enabled){
		ZAssert.notEmpty(ids, "请选择数据");
		ZAssert.notNull(enabled, "状态参数");
		authMenuMapper.updateEnabled(ids,enabled);
	}
	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void batchRemoveAuthMenu(List<Long> ids){
		ZAssert.notEmpty(ids, "请选择数据");
		authMenuMapper.batchDelete(ids);
	}
	 
	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void removeAuthMenu(Long id){
		ZAssert.notNull(id, "请选择数据");
		authMenuMapper.deleteByPrimaryKey(id);
	 }
	 
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<Map<String, Object>> loadAuthMenuTree(Map<String, Object> params) {
		
		AuthMenu rootMenu=authMenuMapper.selectRootMenu();
		
		if(ZObjectUtil.isEmpty(rootMenu)){
			ZAlert.Error("未发现根节点数据，请检查数据");
		}
		ParamMap pm=ParamMap.newPm(QueryType.S_NO_NC);
		String pid=(String) params.get("pid");
		if(ZStrUtil.hasText(pid)){
			pm.addParam("parentId", pid);
		}
		List<Map<String, Object>>  authMenuTree=authMenuMapper.selectAuthMenuTree(pm);
		return authMenuTree;
	}
}